Next | Prev | Up | Top | Contents | Index

Waiting for Time to Pass

The kernel offers functions for timed delays, as summarized in Table 9-21.

Functions for Timed Delays
Function NameHeader FilesCan Sleep?Purpose
delay(D3) ddi.hYDelay for a specified number of clock ticks.
drv_hztousec(D3) ddi.hNConvert clock ticks to microseconds
drv_usectohz(D3) ddi.hNConvert microseconds to clock ticks.
drv_usecwait(D3) ddi.hNBusy-wait for a specified interval.
dtimeout(D3) ddi.h & ksynch.hNSchedule a function execute on a specified processor after a specified length of time.
itimeout(D3) ddi.h & ksynch.hNSchedule a function to be executed after a specified number of clock ticks.
fast_itimeout(D3) ddi.h & ksynch.hNSame as itimeout() but takes an interval in "fast ticks."
fasthzto(D3)types.h & time.hNReturns the value of a struct timeval as a count of "fast ticks."
timeout(D3) ddi.h & ksynch.hNSchedule a function to be executed after a specified number of clock ticks.
untimeout(D3) ddi.hNCancel a previous itimeout or fast_itimeout request.
untimeout_func(D3) ddi.hNCancel a previous itimeout or fast_itimeout request by function name.


Time Units

The basic time unit is the "tick." Its value can differ between hardware platforms and between versions of IRIX. The drvhztousec() and drvusectohz() functions convert between ticks and microseconds in the current system. Use them in order to schedule a delay in a portable mannter. (However, the timer function precision is the tick, not the microsecond.)

The "fast tick" is a fraction of a tick. Like the tick, the fast tick's value can differ between systems. Use fasthzto() to convert from microseconds to fast ticks.


Timer Support

Timer support is based on the idea of a "callback" function. You specify the following to dtimeout(), itimeout(), timeout() or fast_itimeout():

After a delay of at least the length requested, the function is called. The function is entered asynchronously. On a uniprocessor, it can interrupt execution of an upper-half routine. On a multiprocessor, it can execute concurrently with an upper-half routine or with an interrupt handler. You should not rely on the priority level of the function for mutual exclusion (see "Priority Level Functions" for an explanation).

The difference between itimeout() and timeout() is that the latter takes no argument values to be passed to the function when it is called. In order to get a repeated series of timer events, start a new timeout from the callback function.

The untimeout() and untimeout_func() functions cancel a pending timeout. In a loadable driver that has an pfxunload() entry point, cancel any pending timeouts before unloading.

The STREAMS_TIMOUT macro supplies similar timeout capability for a STREAMS driver (see "Special Considerations for Multiprocessing").


Short-Term Delay Support

In rare circumstances, a driver needs to pause briefly between two hardware operations. For example, the Silicon Graphics support for external interrupts in the Challenge and Onyx computers sometimes needs to set a high output level, wait for a brief, precise interval, then set a low output level.

The drv_usecwait() function supports this type of very short, precisely-timed delay. It "spins" for a specified number of microseconds, then returns to the caller. The CPU does nothing else during this period, so clearly a delay of more than a few microseconds can interfere with other work. Furthermore, if interrupts are disabled during the wait, the response to another interrupt is delayed also--the delay contributes directly to the "latency" of interrupt handling.


Next | Prev | Up | Top | Contents | Index